/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "绘图框架.h"

#include <vulkan/vulkan.h>
#include "底层绘图/底层绘图框架.h"

#include "底层绘图/intern/Vulkan/线管/着色器.h"


S_板载缓存* S_光追后端::m_帧渲染信息 = nullptr;

S_结构指针	S_光追后端::g_加速结构创建命令缓存 = {};
S_结构指针	S_光追后端::g_渲染Fence = {};


float32*          S_光追后端::m_f32_gpu_mapptr = nullptr;
int32*            S_光追后端::m_i32_gpu_mapptr = nullptr;
vec2*             S_光追后端::m_vec2_gpu_mapptr = nullptr;
vec3*             S_光追后端::m_vec3_gpu_mapptr = nullptr;
GLSL_RenderFrame* S_光追后端::m_mapPtr_渲染帧数据 = nullptr;
std::mutex        S_光追后端::g_资源分配内存锁;
E_离线渲染状态    S_光追后端::g_渲染状态 = E_离线渲染状态::e_光追渲染_关;

uint32            S_光追后端::g_物体全局显示模式 = E_物体视口显示::e_OVS_预览;



uint8 S_光追后端::g_光追列队 = 3;

S_子集绘图命令* S_绘图框架::g_资源加载管道 = nullptr;

std::vector<S_MapPtrItem> S_光追后端::G纹理;
std::vector<S_MapPtrItem> S_光追后端::G字符纹理;






S_绘图框架::S_绘图框架() {
	m_是否暂停		= true;
	m_场景渲染环境	= nullptr;
}

S_绘图框架::~S_绘图框架() {
}



S_着色::S_着色(const std::string& name) {
	m_ShaderIndex = -1;
}

S_管线::S_管线(const std::string& name) {
	m_Ctx = nullptr;
	m_线管 = nullptr;
	m_线管布局 = nullptr;

	m_管线绑定点 = 0;
	
}



void f_df_设置线管混合模式(S_线管创建参数& 创建参数, E_图层混合模式 混合模式) {
	switch (混合模式) {
		case e_Normal:
			创建参数.m_颜色混合模式 = E_混合模式::e_相加;
			创建参数.m_透明混合模式 = E_混合模式::e_相加;
			
			创建参数.m_源颜色混合因子 = E_混合因子::e_源透明通道;
			创建参数.m_目标颜色混合因子 = E_混合因子::e_一减源透明通道;

			创建参数.m_源透明通道因子 = E_混合因子::e_混合因子一;
			创建参数.m_目标透明通道因子 = E_混合因子::e_混合因子零;

			break;
		case e_Dissolve:
			std::cout<<"f_df_设置线管混合模式 施工中.............. \n";
			break;
		case e_Darken:
			std::cout << "f_df_设置线管混合模式 施工中.............. \n";
			break;
		case e_Multiply:
			创建参数.m_源颜色混合因子 = E_混合因子::e_混合因子零;
			创建参数.m_目标颜色混合因子 = E_混合因子::e_源颜色;

			创建参数.m_源透明通道因子 = E_混合因子::e_混合因子一;
			创建参数.m_目标透明通道因子 = E_混合因子::e_混合因子零;

			创建参数.m_透明混合模式 = E_混合模式::e_相乘;
			创建参数.m_颜色混合模式 = E_混合模式::e_相乘;
			break;
		case e_ColorBurn:
			std::cout << "f_df_设置线管混合模式 施工中.............. \n";
			break;
		case e_LinearBurn:
			std::cout << "f_df_设置线管混合模式 施工中.............. \n";
			break;
		case e_Lighten:
			std::cout << "f_df_设置线管混合模式 施工中.............. \n";
			break;
		case e_Screen:
			创建参数.m_目标颜色混合因子 = E_混合因子::e_混合因子一;
			创建参数.m_源颜色混合因子 = E_混合因子::e_混合因子一;

			创建参数.m_源透明通道因子 = E_混合因子::e_混合因子一;
			创建参数.m_目标透明通道因子 = E_混合因子::e_混合因子一;

			创建参数.m_透明混合模式 = E_混合模式::e_相加;
			创建参数.m_颜色混合模式 = E_混合模式::e_相加;
			break;

		case E_图层混合模式::e_SoftLight:
			创建参数.m_源颜色混合因子 = E_混合因子::e_源颜色;
			创建参数.m_目标颜色混合因子 = E_混合因子::e_一减源颜色;
			
			创建参数.m_源透明通道因子 = E_混合因子::e_源透明通道;
			创建参数.m_目标透明通道因子 = E_混合因子::e_一减源透明通道;

			创建参数.m_透明混合模式 = E_混合模式::e_相加;
			创建参数.m_颜色混合模式 = E_混合模式::e_相加;
			break;

		case E_图层混合模式::e_Line_Normal: {
			创建参数.m_源颜色混合因子 = E_混合因子::e_源颜色;
			创建参数.m_目标颜色混合因子 = E_混合因子::e_一减源颜色;

			创建参数.m_源透明通道因子 = E_混合因子::e_混合因子一;
			创建参数.m_目标透明通道因子 = E_混合因子::e_混合因子零;

			创建参数.m_透明混合模式 = E_混合模式::e_相加;
			创建参数.m_颜色混合模式 = E_混合模式::e_相加;
			break;
		}
		default:
			std::cout << "f_df_设置线管混合模式 方式不支持\n";
			break;
	}
}

void f_df_allocGPU参数缓存槽(S_GPU参数槽* layout, uint16 num) {
	if(layout->m_参数数量 == num) return;

	layout->m_参数数量 = num;

	if (layout->m_参数槽) free(layout->m_参数槽);
	if (layout->m_参数类型) free(layout->m_参数类型);
	if (layout->m_绑定位置) free(layout->m_绑定位置);
	if (layout->m_绑定数量) free(layout->m_绑定数量);

	layout->m_参数槽 = (void**)calloc(layout->m_参数数量, sizeof(void*));
	layout->m_参数类型 = (uint32*)calloc(layout->m_参数数量, sizeof(uint32));
	layout->m_绑定位置 = (uint8*)calloc(layout->m_参数数量, sizeof(uint8));
	layout->m_绑定数量 = (uint16*)calloc(layout->m_参数数量, sizeof(uint16));

	for (uint32 i = 0; i < layout->m_参数数量; ++i) {
		layout->m_参数槽[i] = nullptr;
		layout->m_参数类型[i] = 0;
		layout->m_绑定位置[i] = 0;
		layout->m_绑定数量[i] = 0;
	}

	layout->m_纹理槽 = nullptr;
	layout->m_GPU布局描述 = nullptr;
}

void f_df_freeGPU参数缓存槽(S_GPU参数槽* layout) {
	if (layout->m_参数槽) free(layout->m_参数槽);
	if (layout->m_参数类型) free(layout->m_参数类型);
	if (layout->m_绑定位置) free(layout->m_绑定位置);
	if (layout->m_绑定数量) free(layout->m_绑定数量);
	(*layout) = {};
}

uint32 f_getVk绘制方式(E_绘制方式 方式, E_绘图API apiName) {
	switch (方式) {
		case E_绘制方式::e_画点集:			return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
		case E_绘制方式::e_画线段:			return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
		case E_绘制方式::e_画连续线:		return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
		case E_绘制方式::e_三角形:			return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
		case E_绘制方式::e_三角形带:		return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
		case E_绘制方式::e_画扇形:			return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;

		case E_绘制方式::e_画邻接线段:		return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
		case E_绘制方式::e_画邻接连续线段:	return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY;

		case E_绘制方式::e_画邻接三角形:	return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
		case E_绘制方式::e_画邻接三角形带:	return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
		default:
			break;
	}
	return 0xffffffff;
}

uint32 f_getVk填充方式(E_填充模式 方式, E_绘图API apiName) {
	switch (方式) {
	case E_填充模式::e_填充面:			return VK_POLYGON_MODE_FILL;
	case E_填充模式::e_填充点:			return VK_POLYGON_MODE_POINT;
	case E_填充模式::e_填充线:			return VK_POLYGON_MODE_LINE;
	default:
		break;
	}
	return 0xffffffff;
}

uint32 f_getVk混合模式(E_混合模式 模式) {
	switch (模式) {
	case E_混合模式::e_相加:		return VK_BLEND_OP_ADD;
	case E_混合模式::e_相减:		return VK_BLEND_OP_SUBTRACT;
	case E_混合模式::e_反向相减:	return VK_BLEND_OP_REVERSE_SUBTRACT;
	case E_混合模式::e_最小:		return VK_BLEND_OP_MIN;
	case E_混合模式::e_最大:		return VK_BLEND_OP_MAX;
	case E_混合模式::e_相乘:		return VK_BLEND_OP_MULTIPLY_EXT;
	case E_混合模式::e_零:			return VK_BLEND_OP_ZERO_EXT;
	case E_混合模式::e_源:			return VK_BLEND_OP_SRC_EXT;
	case E_混合模式::e_目标:		return VK_BLEND_OP_DST_EXT;
	case E_混合模式::e_反向:		return VK_BLEND_OP_INVERT_EXT;
	default:
		break;
	}
	return VK_BLEND_OP_MAX_ENUM;
}

uint32 f_getVk混合因子(E_混合因子 因子) {
	switch (因子) {
		case E_混合因子::e_混合因子零:			return VK_BLEND_FACTOR_ZERO;
		case E_混合因子::e_混合因子一:			return VK_BLEND_FACTOR_ONE;
		case E_混合因子::e_源颜色:				return VK_BLEND_FACTOR_SRC_COLOR;
		case E_混合因子::e_一减源颜色:			return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
		case E_混合因子::e_目标颜色:			return VK_BLEND_FACTOR_DST_COLOR;
		case E_混合因子::e_一减目标颜色:		return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
		case E_混合因子::e_源透明通道:			return VK_BLEND_FACTOR_SRC_ALPHA;
		case E_混合因子::e_一减源透明通道:		return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
		case E_混合因子::e_目标透明通道:		return VK_BLEND_FACTOR_DST_ALPHA;
		case E_混合因子::e_一减目标透明通道:	return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
		default:
			break;
	}
	return VK_BLEND_FACTOR_MAX_ENUM;
}

uint32 f_get数据格式(E_数据格式 格式, E_绘图API apiName) {
	switch (格式) {
	case e_F_RGBA:
		return VK_FORMAT_R32G32B32A32_SFLOAT;
	case e_F_R32G32B32A32:
		return VK_FORMAT_R32G32B32A32_SFLOAT;
	case e_F_RGB:
		return VK_FORMAT_R32G32B32_SFLOAT;
	case e_F_R32G32:
		return VK_FORMAT_R32G32_SFLOAT;
	case e_F_R32:
		return VK_FORMAT_R32_SFLOAT;


	case e_I_R32G32B32A32:
		return VK_FORMAT_R32G32B32A32_SINT;
	case e_I_R32G32B32:
		return VK_FORMAT_R32G32B32_SINT;
	case e_I_R32G32:
		return VK_FORMAT_R32G32_SINT;
	case e_I_R32:
		return VK_FORMAT_R32_SINT;


	case e_UI_R32G32B32A32:
		return VK_FORMAT_R32G32B32A32_UINT;
	case e_UI_R32G32B32:
		return VK_FORMAT_R32G32B32_UINT;
	case e_UI_R32G32:
		return VK_FORMAT_R32G32_UINT;
	case e_UI_R32:
		return VK_FORMAT_R32_UINT;


	default:
		break;
	}
	return uint32();
}


/*void S_材质::f_alloc缓存槽(uint16 num) {
}
void S_材质::f_alloc纹理槽(uint16 num) {
}*/


//S_材质::S_材质(S_设备环境* ctx) : m_Ctx(ctx) {
//	m_独立统一缓存 = false;
//	m_材质属性 = {};
//	m_引用着色线管 = false;
//	m_深度遮挡 = true;
//	m_着色线管		= nullptr;
//	m_阴影着色线管	= nullptr;
//	m_环境着色线管	= nullptr;
//	m_几何着色线管	= nullptr;
//	mf_GPU参数配置		= nullptr;
//	mf_GPU材质槽更新	= nullptr;
//	m_材质属性ID = 0;
//	m_纹理槽 = {};
//	//assert(S_材质::g_属性索引);
//	if (S_全局缓存::g_属性索引) {
//		m_材质自定义属性索引 = f_bm_alloc(S_全局缓存::g_属性索引, DEF_网格自定义属性槽数量 * DEF_网格自定义属性槽数量);
//
//		for (uint32 i = 0; i < DEF_网格自定义属性槽数量 * DEF_网格自定义属性槽数量; ++i) {
//			f_buf_属性索引_at(m_材质自定义属性索引, i) = {};
//		}
//	}
//}




S_GPU计算::S_GPU计算(S_设备环境* ctx) {
	m_Pipeline		= nullptr;
	m_Shader		= nullptr;
	m_参数布局		= nullptr;
	m_Ctx			= *ctx;


	m_GPU参数set = 0;
	//mf_GPU参数配置 = nullptr;
}

S_GPU计算::~S_GPU计算() {
	
}









S_光追后端::S_光追后端() {
	m_Ctx                  = nullptr;
	m_光追管线             = nullptr;
	m_GPU参数设置          = nullptr;
	m_顶层加速结构         = nullptr;
	m_渲染纹理             = nullptr;
	m_渲染命令缓存         = nullptr;
	g_渲染Fence            = nullptr;
	g_加速结构创建命令缓存 = nullptr;

	m_投影矩阵				= nullptr;

	
	//m_绘图环境				= nullptr;
	//m_材质             = nullptr;

	//m_场景物体网格指针 = nullptr;
	//m_几何属性         = nullptr;
	//
	m_渲染纹理_最终合成	= nullptr;
	m_渲染纹理_漫反射	= nullptr;
	m_渲染纹理_深度		= nullptr;
	m_渲染纹理_法线		= nullptr;
	m_渲染纹理_自发光	= nullptr;
	m_渲染纹理_光照		= nullptr;
	//
	m_渲染纹理采样器	= nullptr;
	//m_点光源缓冲区     = nullptr;
	//m_聚光灯缓冲区     = nullptr;
	//m_区域光缓冲区     = nullptr;
	//
	//m_区域光物体网格   = nullptr;


	m_渲染             = true;
	m_重新编译线管     = false;
	m_重新设置内部纹理传入参数 = true;

	m_mapPtr_渲染帧数据 = nullptr;


	//m_Frame = 0;

	
	m_渲染器预览参数.光采样 = 6;
	m_渲染器预览参数.反弹次数 = 4;
	m_渲染器预览参数.采样次数 = 64;

	//m_渲染器预览参数.帧采样编号 = 0;

	m_渲染配置.帧采样编号 = 0;
	m_渲染配置.环境材质ID = -1;


	m_分块渲染 = false;
	m_瓦片大小 = {1024,1024};

}

S_光追后端::~S_光追后端() {
	m_渲染 = false;
}

int32 S_光追后端::f_需要要加载纹理数() {
	return m_纹理绑定计数;
}

void S_光追后端::f_重置渲染帧记录() {
	if (m_帧渲染信息) {
		m_mapPtr_渲染帧数据->m_Frame = 0;
		//m_渲染器预览参数.帧采样编号 = 0;
	}
	//m_Frame = 0;
}

uint32 S_光追后端::f_递增渲染帧记录() {
	++(m_mapPtr_渲染帧数据->m_Frame);
	return (m_mapPtr_渲染帧数据->m_Frame);
}

void S_光追后端::f_mapGPU参数() {
	
	f_buf_map板载缓存<S_LightParallel>(f_buf_getGlobal().m_平行光缓冲区);
	f_buf_map板载缓存<S_LightArea>(f_buf_getGlobal().m_区域光缓冲区);
	f_buf_map板载缓存<S_LightSpot>(f_buf_getGlobal().m_聚光灯缓冲区);
}

void S_光追后端::f_unmapGPU参数() {
	
	f_buf_unmap板载缓存(f_buf_getGlobal().m_平行光缓冲区);
	f_buf_unmap板载缓存(f_buf_getGlobal().m_区域光缓冲区);
	f_buf_unmap板载缓存(f_buf_getGlobal().m_聚光灯缓冲区);
}

void S_光追后端::f_resizeGPU参数() {
	if (f_buf_getGlobal().m_平行光缓冲区->m_分配器.maxNum) f_buf_resize(f_buf_getGlobal().m_平行光缓冲区, f_buf_getGlobal().m_平行光缓冲区->m_分配器.maxNum);
	if (f_buf_getGlobal().m_区域光缓冲区->m_分配器.maxNum) f_buf_resize(f_buf_getGlobal().m_区域光缓冲区, f_buf_getGlobal().m_区域光缓冲区->m_分配器.maxNum);
	if (f_buf_getGlobal().m_聚光灯缓冲区->m_分配器.maxNum) f_buf_resize(f_buf_getGlobal().m_聚光灯缓冲区, f_buf_getGlobal().m_聚光灯缓冲区->m_分配器.maxNum);
}





C_场景渲染环境::C_场景渲染环境(S_设备环境& ctx) {
	auto& rf = *f_vk_get绘图框架(ctx);

	m_管线参数设置_None						= new C_VkDescriptorSet(ctx, *rf.m_着色布局设置_None);
	m_管线参数设置_VS_Proj					= new C_VkDescriptorSet(ctx, *rf.m_着色布局设置_VS_Proj);
	m_管线参数设置_VS_Mat4					= new C_VkDescriptorSet(ctx, *rf.m_着色布局设置_VS_Mat4);
	m_管线参数设置_F_L3_ImageSampleArray	= new C_VkDescriptorSet(ctx, *rf.m_着色布局设置_Comp_L3_ImageSampleArray);

}

C_场景渲染环境::~C_场景渲染环境() {
	delete m_管线参数设置_None;					
	delete m_管线参数设置_VS_Proj;				
	delete m_管线参数设置_VS_Mat4;				
	delete m_管线参数设置_F_L3_ImageSampleArray;


}

//void C_场景渲染环境::f_添加管线(S_材质管线* 管线, E_管线槽 槽) {
//	switch (槽) {
//		case E_管线槽::e_颜色渲染: {
//			m_DS_颜色 = new C_VkDescriptorSet(管线->m_着色线管->m_Pipeline, 管线->m_着色线管->m_Shader);
//			break;
//		}
//		default:
//			break;
//	}
//}


struct S_VK命令缓存池 {
	std::vector<VkCommandPool>		m_pool;
	std::vector<VkCommandBuffer>	m_commandCache;

	VkCommandPool	m_主命令缓存池;
	VkCommandBuffer m_主命令缓存;

	VkDevice m_device;
	uint32 m_队列族索引;

	S_VK命令缓存池(VkDevice device, uint32 队列族索引) : m_device(device), m_队列族索引(队列族索引) {
		VkCommandPoolCreateInfo poolInfo{};
		poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
		poolInfo.queueFamilyIndex = m_队列族索引;
		poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
		vkCreateCommandPool(m_device, &poolInfo, nullptr, &m_主命令缓存池);

		VkCommandBufferAllocateInfo allocInfo{};
		allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
		allocInfo.commandPool = m_主命令缓存池;
		allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
		allocInfo.commandBufferCount = 1;
		vkAllocateCommandBuffers(m_device, &allocInfo, &m_主命令缓存);
	}

	~S_VK命令缓存池() {
		vkFreeCommandBuffers(m_device, m_主命令缓存池, 1, &m_主命令缓存);
		vkDestroyCommandPool(m_device, m_主命令缓存池, nullptr);

		uint32 num = m_pool.size();
		vkFreeCommandBuffers(m_device, m_主命令缓存池, num, m_commandCache.data());
		for (uint32 i = 0; i < num; ++i) {
			vkDestroyCommandPool(m_device, m_pool[i], nullptr);
		}
	}

	void f_创建次级命令缓存() {
		VkCommandPoolCreateInfo info{};
		info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
		info.queueFamilyIndex = m_队列族索引;
		info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT |	// 允许 reset
					VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;				// 大量短命令时更快

		VkCommandPool pool;
		vkCreateCommandPool(m_device, &info, nullptr, &pool);
		m_pool.push_back(pool);

		VkCommandBufferAllocateInfo allocInfo{};
		allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
		allocInfo.commandPool = pool;
		allocInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
		allocInfo.commandBufferCount = 1;

		VkCommandBuffer com;
		vkAllocateCommandBuffers(m_device, &allocInfo, &com);
		m_commandCache.push_back(com);
	}
};

S_GPU命令缓存::S_GPU命令缓存(S_设备环境& ctx, uint32 线程数量) {
	auto device = f_vk_getDevice(ctx);

	S_VK命令缓存池* 命令缓存池 = new S_VK命令缓存池(device, ctx.m_逻辑设备.队列族索引);

	for (uint32 i = 0; i < 线程数量; ++i) {
		命令缓存池->f_创建次级命令缓存();
	}
	
	m_池 = (S_结构对象*)命令缓存池;
}

S_GPU命令缓存::~S_GPU命令缓存() {
	delete m_池;
}

void S_GPU命令缓存::f_创建命令缓存(uint32 线程索引) {
	auto& 池 = *(S_VK命令缓存池*)m_池;
	auto device = f_vk_getDevice(m_ctx);

	//VkCommandBuffer cb;
	//VkCommandBufferAllocateInfo ai{};
	//ai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	//ai.commandPool = 池.pool;
	//ai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
	//ai.commandBufferCount = 1;
	//vkAllocateCommandBuffers(device, &ai, &cb);
	//
	//池.commandCache.push_back(cb);
}

void S_GPU命令缓存::f_begin(uint32 线程ID) {
	auto& 池 = *(S_VK命令缓存池*)m_池;

	vkResetCommandBuffer(池.m_commandCache[线程ID], 0);

	VkCommandBufferBeginInfo bi{};
	bi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	bi.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
	vkBeginCommandBuffer(池.m_commandCache[线程ID], &bi);

}

void S_GPU命令缓存::f_end(uint32 线程ID) {
	auto& 池 = *(S_VK命令缓存池*)m_池;
	vkEndCommandBuffer(池.m_commandCache[线程ID]);
}

void S_GPU命令缓存::submit() {
	auto& 池 = *(S_VK命令缓存池*)m_池;

	VkCommandBufferBeginInfo bi{};
	bi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	vkBeginCommandBuffer(池.m_主命令缓存, &bi);

	// 执行所有 Secondary CB
	vkCmdExecuteCommands(池.m_主命令缓存, 池.m_commandCache.size(), 池.m_commandCache.data());

	vkEndCommandBuffer(池.m_主命令缓存);

	VkSubmitInfo si{};
	si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	si.commandBufferCount = 1;
	si.pCommandBuffers = &池.m_主命令缓存;

	VkQueue* queue = (VkQueue*)m_ctx.m_逻辑设备.列队;
	vkQueueSubmit(queue[uint32(E_VK列队类型::e_缓存)], 1, &si, VK_NULL_HANDLE);
	vkQueueWaitIdle(queue[uint32(E_VK列队类型::e_缓存)]);
}


void S_GPU命令缓存::f_begin() {
	auto& 池 = *(S_VK命令缓存池*)m_池;

	vkResetCommandBuffer(池.m_主命令缓存, 0);

	VkCommandBufferBeginInfo bi{};
	bi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	vkBeginCommandBuffer(池.m_主命令缓存, &bi);

}

void S_GPU命令缓存::f_end() {
	auto& 池 = *(S_VK命令缓存池*)m_池;
	vkEndCommandBuffer(池.m_主命令缓存);

	VkSubmitInfo si{};
	si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	si.commandBufferCount = 1;
	si.pCommandBuffers = &池.m_主命令缓存;

	VkQueue* queue = (VkQueue*)m_ctx.m_逻辑设备.列队;
	vkQueueSubmit(queue[uint32(E_VK列队类型::e_缓存)], 1, &si, VK_NULL_HANDLE);
	vkQueueWaitIdle(queue[uint32(E_VK列队类型::e_缓存)]);
}


